{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 一 变量与注释\n",
    "变量是用来从内存找到某个东西的标记"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.1 基础知识"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1.1 变量常见用法\n",
    "1. 变量解包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "usernames = ['piglei', 'raymond']\n",
    "author, reader = usernames\n",
    "attrs = [1, ['piglei', 100]]\n",
    "userid, (username, score) = attrs\n",
    "            #动态解包\n",
    "data = ['piglei', 'apple', 'orange', 'banana', 100]\n",
    "username, *fruits, score = data\n",
    "        #2.单下划线变量名_\n",
    "author, _ = usernames\n",
    "username, *_, score = data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1.2 给变量注明类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    " #Sphinx格式文档\n",
    "def remove_invalid(items):\n",
    "    \"\"\"剔除items里无效的元素\n",
    "\n",
    "    :param items: 待剔除对象\n",
    "    :typr items:包含整数的列表，[int, ...]\n",
    "    \"\"\"\n",
    "    ... "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1.3 变量命名原则\n",
    "1. \"\"\"计算机科学领域只有两件难事：缓存失败和命名\"\"\"\n",
    "2. 遵循**PEP8**原则\n",
    "    - 驼峰派：CamelCase 蛇形派：snake_case\n",
    "    - 对于普通变量，使用蛇形命名法，eg：max_value；\n",
    "    - 对于常量，采用全大写字母，使用下划线连接，比如MAX_VALUE;\n",
    "    - 如果变量标记为“仅内部使用”，为其增加下划线前缀，比如_local_val;\n",
    "    - 当名字与Python关键字冲突时，在变量末尾追加下划线；\n",
    "    - 类名使用驼峰风格，函数使用蛇形风格\n",
    "3. 描述性要强\n",
    "4. 要尽量短\n",
    "    - 不要超过四个单词\n",
    "5. 要匹配类型\n",
    "    - 布尔类型：is_superuser, has_errors, allow_empty\n",
    "    - int/float类型：\n",
    "    - 释义为数字的所有单词，比如port(端口号)，age(年龄)，radius（半径）\n",
    "    - 使用以_id结尾的单词，比如user_id，host_id\n",
    "    - 使用length/count开头的单词，比如length of username,user_count\n",
    "    - 尽量别用单词的复数形式表示int类型，建议用类似number of apples,trips_count这类\n",
    "6. 超短命名\n",
    "    - 数组索引三剑客 i,j,k\n",
    "    - 某个整数 n\n",
    "    - 某个字符串 s\n",
    "    - 某个异常 e\n",
    "    - 文件类型 fp\n",
    "``` python\n",
    " from django.utils.translation import gettext as _\n",
    "``` \n",
    "7. 在一段代码内不要出现多个相似的变量名，比如同时使用user,user1,user2；\n",
    "    - 可以尝试换词来简化复合变量名\n",
    "    - 如果找不出合适的名字，打开github看别人怎么写\n",
    "8. 注释基础知识\n",
    "    - 代码内注释\n",
    "    - 接口注释 \"\"\" \"\"\"\n",
    "    - 常见错误\n",
    "        - 用注释屏蔽代码\n",
    "        - 用注释复述代码\n",
    "        - 弄错接口注释的受众"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2案例故事\n",
    "请用冒泡排序法，把较大的数字放在后面。注意：默认所有的偶数比基数大1.\n",
    "```python \n",
    "    numbers = [23, 32, 1, 3, 4, 19, 20, 2, 4]\n",
    "    magic_bubble_sort(numbers)\n",
    "    [1, 3, 19， 23， 2， 4， 4， 20， 32]\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 3, 19, 23, 2, 4, 4, 20, 32]\n"
     ]
    }
   ],
   "source": [
    "#不带类型声明的函数\n",
    "numbers = [23, 32, 1, 3, 4, 19, 20, 2, 4]\n",
    "def magic_bubble_sort(numbers):\n",
    "    j = len(numbers) - 1\n",
    "    while j>0:\n",
    "        for i in range(j):\n",
    "            if numbers[i] % 2 == 0 and numbers[i+1] % 2 == 1:\n",
    "                numbers[i], numbers[i+1] = numbers[i+1], numbers[i]\n",
    "                continue\n",
    "            elif(numbers[i] % 2 == numbers[i+1] % 2) and numbers[i] > numbers[i+1]:\n",
    "                numbers[i], numbers[i+1] = numbers[i+1], numbers[i]\n",
    "                continue   \n",
    "        j -= 1\n",
    "    return numbers\n",
    "print(magic_bubble_sort(numbers))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#带有声明的函数\n",
    "numbers = [23, 32, 1, 3, 4, 19, 20, 2, 4]\n",
    "def magic_bubble_sort(numbers: list[int]):\n",
    "    \"\"\"有魔力的冒泡排序法，默认所有的偶数比奇数大\n",
    "    :param numbers: 需要排序的列表，函数会直接修改原始列表    \n",
    "    \"\"\"\n",
    "    stop_position = len(numbers) - 1\n",
    "    while stop_position > 0:\n",
    "        for i in range(stop_position):\n",
    "            current, next_ = numbers[i], numbers[i+1]\n",
    "            current_is_even, next_is_even = current % 2 == 0, next_is_even % 2 == 0\n",
    "            should_swap = False\n",
    "\n",
    "            #交换位置的两个条件：\n",
    "            #- 前面是偶数，后面是奇数\n",
    "            #- 前面和后面同为偶数或奇数，且前面大于后面\n",
    "            if current_is_even and not next_is_even:\n",
    "                should_swap = True\n",
    "            elif current_is_even == next_is_even and current > next_:\n",
    "                should_swap = True\n",
    "            if should_swap:\n",
    "                numbers[i], numbers[i+1] = numbers[i+1], numbers[i]\n",
    "        stop_position -= 1\n",
    "    return numbers\n",
    "#注意：此处变量是next_而非next，这是因为已经有一个内置函数使用了next这个名字\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3编程建议\n",
    "### 1.3.1 保持变量的一致性\n",
    "  - 名字一致性和类型一致性\n",
    "  - 名字一致性是指同一个项目（或者函数、模块）中，对一类事物的称呼不要变来变去\n",
    "  - 类型一致性是指不要把同一变量重复指向不同类型的值\n",
    "### 1.3.2 变量定义尽量靠近使用\n",
    "总是从代码的职责出发，而不是其他东西。\n",
    "### 1.3.3 定义临时变量提高可读性\n",
    "### 1.3.4 同一作用域不要太多变量\n",
    "### 1.3.5 能不定义变量就别定义\n",
    "### 1.3.6 不要使用locals()\n",
    "### 1.3.6 空行也是一种“注释”\n",
    "### 1.3.7 先写注释，后写代码"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "vs_script",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
